package com.android.demo.widget;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Handler;
import android.telephony.TelephonyManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.android.demo.R;

/**
 * 通用工具类，以static方式提供，调用者不能继承使用，也不能实例化。 目前提供显示toast功能，以后会在需要时添加其它的常用功能
 * 
 * @author shawn
 */
public final class Utils {
	public static final int YEAR = 315360000;
	public static final int DAY = 86400;
	public static final int HOUR = 3600;
	public static final int MINS = 60;

	public static CharSequence[] EMPTY_ARRAY = new CharSequence[0];
	public static final String PREFS_NAME = "cn.com.nd.momo";
	public static final String IP_PREFIX = "ip_prefix";
	public static final char IP_PREFIX_BREAK_CHAR = ',';
	private static final String defaultIpPrefix = "12593,17951";
	/**
	 * The UTC time zone (often referred to as GMT).
	 */
	public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("GMT");

	private Utils() {
		// 不让调用者继承来调用，以保护类的封装
	}

	/**
	 * 把秒 转化成hh:mm:ss的时间格式， 若秒合算之后达到一个小时，则以"HH:mm:ss"格式提供
	 * 
	 * @param second
	 * @return
	 */
	public static String formatSecondsToMinsWithSecs(long second) {
		final long oneHourToSeconds = 3600;
		String pattern = "";
		if (oneHourToSeconds > second)
			pattern = "mm:ss";
		else
			pattern = "hh:mm:ss";
		FastDateFormat df = FastDateFormat.getInstance(pattern, null, null);
		return df.format(second * 1000);
	}

	/**
	 * 把秒 转化成hh:mm:ss的时间格式， 若秒合算之后达到一个小时，则以"HH:mm:ss"格式提供
	 * 
	 * @param second
	 * @return
	 */
	public static String formatSecondsToCommaStyle(long second) {
		final long oneHourToSeconds = 3600;
		String pattern = "";
		if (oneHourToSeconds > second)
			pattern = "mm‘ss";
		else
			pattern = "hh‘mm‘ss";
		FastDateFormat df = FastDateFormat.getInstance(pattern, UTC_TIME_ZONE, null);
		return df.format(second * 1000);
	}

	/**
	 * 将时间数值转化为YYYY/MM/DD HH:MM:SS格式
	 * 
	 * @param milliseconds
	 * @return
	 */
	public static String formatDateToNormalRead(String milliseconds) {
		String style = "yyyy/MM/dd HH:mm:ss";
		long value = Long.parseLong(milliseconds);
		FastDateFormat df = FastDateFormat.getInstance(style, null, null);
		return df.format(new Date(value));
	}

	/**
	 * 转化时间为某年某月某日
	 * 
	 * @author cmk
	 */
	public static String formatSecondsToDay(long second) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(second);
		String output = Integer.toString(calendar.get(Calendar.YEAR)) + "年" + Integer.toString(calendar.get(Calendar.MONTH) + 1) + "月"
				+ Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)) + "日";
		return output;
	}

	public static String formatEpochToDay(long second) {
		EpochDate epochDate = new EpochDate(second);
		Calendar calendar = epochDate.getCalendar();
		String output = Integer.toString(calendar.get(Calendar.YEAR)) + "年" + Integer.toString(calendar.get(Calendar.MONTH) + 1) + "月"
				+ Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)) + "日";
		return output;
	}

	/**
	 * 显示toast，主要用于调试
	 * 
	 * @param context
	 * @param strToDisplay
	 *            ，0为短显示，1为长显示
	 * @param delay
	 */
	public static void displayToast(final Context context, final String strToDisplay, int delay) {
		Toast.makeText(context, strToDisplay, delay == 0 ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
	}

	/**
	 * 将日期格式化为容易理解的格式
	 * 
	 * @param v
	 * @param value
	 */
	public static void formateDateToEasyRead(TextView v, String value) {
		String result = formateDataToEasyReadForCallLogUse(value);
		v.setText(null == result ? "" : result);
	}

	public static String formateDataToEasyReadForCallLogUse(String timeValue) {
		long callTime = Long.parseLong(timeValue);
		long currentTime = System.currentTimeMillis();
		long durationSecs = (currentTime - callTime) / 1000;
		Date callDate = new Date(callTime);
		SimpleDateFormat hmf = new SimpleDateFormat("HH:mm");
		String result = "";
		if (durationSecs < DAY)
			result = hmf.format(callDate);
		else if (durationSecs < DAY * 2) {
			result = new StringBuilder("昨天").append(hmf.format(callDate)).toString();
		} else if (durationSecs < DAY * 3) {
			result = new StringBuilder("前天").append(hmf.format(callDate)).toString();
		}else {
			SimpleDateFormat sdf;
			if (durationSecs <= YEAR)
				sdf = new SimpleDateFormat("MM/dd");
			else
				sdf = new SimpleDateFormat("yy/MM/dd");
			result = sdf.format(callDate);
		}
		return result;
	}

	/**
	 * @param timeValue
	 * @return 格式化后的时间
	 */
	public static String formateDateToEasyReadForIMUse(String timeValue) {
		long callTime = Long.parseLong(timeValue);
		long currentTime = System.currentTimeMillis();
		long durationSecs = (currentTime - callTime) / 1000;
		Date callDate = new Date(callTime);
		SimpleDateFormat hmf = new SimpleDateFormat("HH:mm");
		String result = "";
		if (durationSecs < 20)
			result = "刚刚";
		else if (durationSecs < MINS)
			result = durationSecs + "秒前";
		else if (durationSecs >= MINS && durationSecs < HOUR)
			result = (durationSecs / MINS) + "分钟前";
		else if (durationSecs >= HOUR && durationSecs < DAY)
			result = (durationSecs / HOUR) + "小时前";
		else if (durationSecs >= DAY && durationSecs < DAY * 2) {
			result = new StringBuilder("昨天").append(hmf.format(callDate)).toString();
		} else if (durationSecs >= DAY * 2 && durationSecs < DAY * 3) {
			result = new StringBuilder("前天").append(hmf.format(callDate)).toString();
		} else if (durationSecs >= DAY * 3 && (durationSecs < DAY * 7)) {
			long days = durationSecs / DAY;
			result = new StringBuilder().append(days).append("天前").append(hmf.format(callDate)).toString();
		} else if (durationSecs >= DAY * 7) {
			SimpleDateFormat sdf;
			if (durationSecs <= YEAR)
				sdf = new SimpleDateFormat("MM/dd HH:mm");
			else
				sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			result = sdf.format(callDate);
		}
		return result;
	}

	public static String formatSize2String(long size) {
		DecimalFormat df = new DecimalFormat("0.00");
		String mysize = "";
		if (size > 1024 * 1024) {
			mysize = df.format(size / 1024f / 1024f) + "M";
		} else if (size > 1024) {
			mysize = df.format(size / 1024f) + "K";
		} else {
			mysize = size + "B";
		}
		return mysize;
	}

	/**
	 * 拨打电话
	 * 
	 * @param number
	 *            电话号码
	 */
	public static void placeCall(final String number, final Context context) {
		if (null == number || number.length() < 1)
			return;
		Intent intent = new Intent(Intent.ACTION_CALL,// ACTION_CALL_PRIVILEGED
				Uri.fromParts("tel", number, null));
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent);
	}

	/**
	 * 发送短信
	 * 
	 * @param phoneNumber
	 */
	public static void sendMsg(String phoneNumber, Context context) {
		// Intent intent = new Intent(context, ComposeSMSActivity.class);
		if (!isNetworkAvailable(context, true)) {
			return;
		}
		if (phoneNumber.length() > 0) {
			Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + phoneNumber));
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			context.startActivity(intent);
		} else {
			Utils.displayToast(context, "短信接收方号码为空！", 0);
		}
	}

	public static void sendMsgToMultiContacts(final String phoneNumber, Context context) {
		if (!isNetworkAvailable(context, true)) {
			return;
		}
		if (phoneNumber.length() > 0) {
			// Intent intent = new Intent(Intent.ACTION_VIEW);
			// intent.putExtra("address", phoneNumber);
			// intent.setType("vnd.android-dir/mms-sms");
			Intent smsIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + phoneNumber));
			smsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			context.startActivity(smsIntent);
		} else {
			Utils.displayToast(context, "短信接收方号码为空！", 0);
		}
	}

	public static boolean isNetworkAvailable(Context context, boolean needToastTips) {
		TelephonyManager telMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		int simState = telMgr.getSimState();
		if (simState != TelephonyManager.SIM_STATE_READY) {
//			if (needToastTips)
//				displayToast(context, context.getResources().getString(R.string.sim_card_network_locked_please_contact_provider), 0);
			return false;
		}
		return true;
	}

	/**
	 * 如果字串对象为NULL,则让其返回空串
	 * 
	 * @param str
	 * @return
	 */
	public static String setStringToBlankIfNull(String str) {
		return (null == str ? "" : str);
	}

	/**
	 * 如果没有网络则弹出连接提示
	 * 
	 * @param content
	 * @return
	 */

	/**
	 * 判断有无wifi连接
	 */

	/**
	 * 压缩获取本地图片, size为边界
	 */
	public static Bitmap getLocalBitmap(String path, int size) {
		BitmapFactory.Options options = new BitmapFactory.Options();

		options.outHeight = size;

		options.inJustDecodeBounds = true;

		// 获取bitmap宽高
		Bitmap bm = BitmapFactory.decodeFile(path, options);

		options.inJustDecodeBounds = false;
		int be = options.outHeight / (int) (size / 10);
		if (be % 10 != 0)
			be += 10;

		be = be / 10;
		if (be <= 0)
			be = 1;

		options.inSampleSize = be;
		bm = BitmapFactory.decodeFile(path, options);

		return bm;
	}

	/**
	 * get degree from exif
	 */
	public static int getDegree(String filename) {
		int result = 0;
		int orientation = 0;
		try {
			ExifInterface exif = new ExifInterface(filename);
			orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);

		} catch (Exception e) {
		}

		switch (orientation) {
		case ExifInterface.ORIENTATION_ROTATE_90:
			result = 90;
			break;
		case ExifInterface.ORIENTATION_ROTATE_180:
			result = 180;
			break;
		case ExifInterface.ORIENTATION_ROTATE_270:
			result = 270;
			break;
		}

		return result;
	}

	/**
	 * 获取压缩
	 */
	public static byte[] compressBitmapBytes(String path, int size) {
		Bitmap bm = getLocalBitmap(path, size);
		ByteArrayOutputStream stream = new ByteArrayOutputStream();

		// create explicit picture
		int max = bm.getWidth() > bm.getHeight() ? bm.getWidth() : bm.getHeight();
		int min = bm.getWidth() < bm.getHeight() ? bm.getWidth() : bm.getHeight();
		min = size * min / max;
		max = size;
		if (bm.getWidth() > bm.getHeight()) {
			bm = Bitmap.createScaledBitmap(bm, max, min, true);
		} else {
			bm = Bitmap.createScaledBitmap(bm, min, max, true);
		}

		// rotate from exif
		int degree = getDegree(path);
		if (degree > 0) {
			Matrix matrix = new Matrix();
			matrix.postRotate(degree);

			bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
		}

		bm.compress(CompressFormat.JPEG, 80, stream);
		byte[] result = stream.toByteArray();
		try {
			stream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static void DialogNetWork(final Activity context) {
		new AlertDialog.Builder(context).setTitle("网络未连接,请设置网络").setIcon(android.R.drawable.ic_dialog_info)
				.setPositiveButton("设置网络", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						context.startActivityForResult(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS), 0);
					}
				}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				}).show();
	}

	public static void AlertDialogIntent(final Context context, final String title, final String yes, String no,
			@SuppressWarnings("rawtypes") final Class activityClass) {
		new AlertDialog.Builder(context).setTitle(title).setIcon(android.R.drawable.ic_dialog_info)
				.setPositiveButton(yes, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						Intent intent = new Intent(context, activityClass);
						context.startActivity(intent);
					}
				}).setNegativeButton(no, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				}).show();
	}

	/**
	 * 退出程序
	 */
	public static void DialogExit(final Activity context) {
		new AlertDialog.Builder(context).setTitle("Exit?").setIcon(android.R.drawable.ic_dialog_info)
				.setPositiveButton("YES", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						context.finish();
					}
				}).setNegativeButton("NO", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				}).show();
	}

	/**
	 * 显示/隐藏 对话框
	 */
	private static AlertDialog mAD = null;

	public static void showWaitDialog(String txt, Context context) {
		if (mAD == null) {
			mAD = new AlertDialog.Builder(context).setTitle(txt).setIcon(android.R.drawable.ic_dialog_info).show();
		} else {
			mAD.dismiss();
			mAD = null;
		} 
	}

	public static void hideWaitDialog() {
		if (mAD != null) {
			mAD.dismiss();
			mAD = null;
		}
	}

	public static String getMD5OfBytes(byte[] buffer) {
		if (buffer==null) return "";
		String result = "";

		MessageDigest complete;
		try {
			complete = MessageDigest.getInstance("MD5");
			byte[] b = complete.digest(buffer);
			for (int i = 0; i < b.length; i++) {
				result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		return result;
	}
	
	public static String getMD5OfString(String str) {
		return getMD5OfBytes(str.getBytes());
	}

	/**
	 * 这个方法来自apache langs
	 */
	public static String replaceChars(String str, String searchChars, String replaceChars) {
		if (isEmpty(str) || isEmpty(searchChars)) {
			return str;
		}
		if (replaceChars == null) {
			replaceChars = EMPTY;
		}
		boolean modified = false;
		int replaceCharsLength = replaceChars.length();
		int strLength = str.length();
		StringBuilder buf = new StringBuilder(strLength);
		for (int i = 0; i < strLength; i++) {
			char ch = str.charAt(i);
			int index = searchChars.indexOf(ch);
			if (index >= 0) {
				modified = true;
				if (index < replaceCharsLength) {
					buf.append(replaceChars.charAt(index));
				}
			} else {
				buf.append(ch);
			}
		}
		if (modified) {
			return buf.toString();
		}
		return str;
	}

	/**
	 * 这个方法来自apache langs
	 */
	public static boolean isEmpty(CharSequence cs) {
		return cs == null || cs.length() == 0;
	}

	/**
	 * 这个方法来自apache langs
	 * 
	 * @since 2.0
	 */
	public static final String EMPTY = "";

	/**
	 * 这个方法来自apache langs
	 */
	public static String replaceOnce(String text, String searchString, String replacement) {
		return replace(text, searchString, replacement, 1);
	}

	/**
	 * 这个方法来自apache langs
	 */
	public static String replace(String text, String searchString, String replacement, int max) {
		if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
			return text;
		}
		int start = 0;
		int end = text.indexOf(searchString, start);
		if (end == INDEX_NOT_FOUND) {
			return text;
		}
		int replLength = searchString.length();
		int increase = replacement.length() - replLength;
		increase = (increase < 0 ? 0 : increase);
		increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
		StringBuilder buf = new StringBuilder(text.length() + increase);
		while (end != INDEX_NOT_FOUND) {
			buf.append(text.substring(start, end)).append(replacement);
			start = end + replLength;
			if (--max == 0) {
				break;
			}
			end = text.indexOf(searchString, start);
		}
		buf.append(text.substring(start));
		return buf.toString();
	}

	public static final int INDEX_NOT_FOUND = -1;

	public static String removeStartIgnoreCase(String str, String remove) {
		if (isEmpty(str) || isEmpty(remove)) {
			return str;
		}
		if (startsWithIgnoreCase(str, remove)) {
			return str.substring(remove.length());
		}
		return str;
	}

	public static boolean startsWithIgnoreCase(String str, String prefix) {
		return startsWith(str, prefix, true);
	}

	/**
	 * <p>
	 * Check if a String starts with a specified prefix (optionally case insensitive).
	 * </p>
	 * 
	 * @see java.lang.String#startsWith(String)
	 * @param str
	 *            the String to check, may be null
	 * @param prefix
	 *            the prefix to find, may be null
	 * @param ignoreCase
	 *            inidicates whether the compare should ignore case (case insensitive) or not.
	 * @return <code>true</code> if the String starts with the prefix or both <code>null</code>
	 */
	private static boolean startsWith(String str, String prefix, boolean ignoreCase) {
		if (str == null || prefix == null) {
			return (str == null && prefix == null);
		}
		if (prefix.length() > str.length()) {
			return false;
		}
		return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
	}

	/**
	 * 简单实现字符串的分隔,摘自apache lang里的StringUtils.java，但修改了排除空字符
	 */
	public static String[] split(final String strToSplit, final char separator) {
		if (strToSplit.length() < 1)
			return new String[0];
		List<String> matchList = new ArrayList<String>();
		int len = strToSplit.length();
		int i = 0, start = 0;
		while (i < len) {
			if (strToSplit.charAt(i) == separator) {
				String subStr = strToSplit.substring(start, i);
				if (subStr.length() > 0)
					matchList.add(subStr);
				start = ++i;
				continue;
			}
			i++;
		}
		if (start < len) {
			String subStr = strToSplit.substring(start, i);
			if (subStr.length() > 0)
				matchList.add(subStr);
		}
		return matchList.toArray(new String[matchList.size()]);
	}

	public static void showKeyboard(final Context context, final EditText txt) {
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(txt, 0);
			}
		}, 100);
	}

	public static String ignoreIpPrefix(final String phoneNumber, final Context context) {
		if (null == phoneNumber || phoneNumber.length() < 6)
			return phoneNumber;
		String[] ipPrefixList = getIpPrefixList(context);
		for (int i = 0; i < ipPrefixList.length; i++) {
			String eachIpPrefix = ipPrefixList[i];
			if (hasPrefix(phoneNumber, eachIpPrefix))
				return phoneNumber.substring(eachIpPrefix.length());
		}
		// 过滤+86
		final String plus86 = "+86";
		if (hasPrefix(phoneNumber, plus86))
			return phoneNumber.substring(plus86.length());
		return phoneNumber;
	}

	private static boolean hasPrefix(final String dest, final String prefix) {
		int index = dest.indexOf(prefix);
		if (-1 == index)
			return false;
		int prefixLen = prefix.length();
		if (prefixLen >= dest.length())
			return false;
		if (0 == index)
			return true;
		return false;
	}

	public static boolean hasIpPrefix(final String phoneNumber, final Context context) {
		if (null == phoneNumber || phoneNumber.length() < 6)
			return false;
		String[] ipPrefixList = getIpPrefixList(context);
		for (int i = 0; i < ipPrefixList.length - 1; i++) {
			String eachIpPrefix = ipPrefixList[i];
			int index = phoneNumber.indexOf(eachIpPrefix);
			if (-1 == index)
				continue;
			int ipPrefixLen = eachIpPrefix.length();
			if (ipPrefixLen >= phoneNumber.length())
				continue;
			if (0 == index)
				return true;
		}
		return false;
	}
	
	public static String getIMSINumber(final Context context) {
		 TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		 
//		 String deviceid = tm.getDeviceId();
//		 String tel = tm.getLine1Number();
//		 String  imei = tm.getSimSerialNumber();      
		 String imsi = tm.getSubscriberId();
		return imsi;
	}
	
	public static String getMd5OfIMSINumber(final Context context) {
		String str = getIMSINumber(context);
		if (str==null||str=="") return "";
		
		return getMD5OfString(str);
	}

	
	public static void ExecLater(final Runnable runable, final int delay) {
		final Handler handler = new Handler();
		Timer time = new Timer();
        time.schedule(new TimerTask() {
			@Override
			public void run() {
				handler.post(runable);
			}
		}, delay);
	}
	
	/**
	 * 忽略IP前缀
	 */
	private static String ipPrefixBeforeModify = "";
	private static String[] ipPrefixListBeforeModify = new String[0];

	private static String[] getIpPrefixList(final Context context) {
		SharedPreferences statesEdit = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
		String ipPrefix = statesEdit.getString(IP_PREFIX, defaultIpPrefix);
		if (!ipPrefix.equalsIgnoreCase(ipPrefixBeforeModify)) {
			ipPrefixBeforeModify = ipPrefix;
			ipPrefixListBeforeModify = Utils.split(ipPrefix, Utils.IP_PREFIX_BREAK_CHAR);
		}
		return ipPrefixListBeforeModify;
	}
}
